#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
     HANDLE console = GetStdHandle(STD_INPUT_HANDLE);
     DWORD mode;
     GetConsoleMode(console, &mode);
     SetConsoleMode(console, mode & ~ENABLE_LINE_INPUT);

     char answer;
     bool have_key;
     bool grate_locked;

start_game:
     have_key = false;
     grate_locked = true;

     cout << "Welcome to the adventure. To play, I will describe your situation, and you must" << endl;
     cout << "choose what to do." << endl;
     cout << "Good luck adventurer!" << endl;
     cout << endl;

describe_forest:
     cout << "You are in a mysterious forest. Beside you is a small stream. The forest is" << endl;
     cout << "unexpectedly quiet. The only sound is the gentle trickle of the water. There is" << endl;
     cout << "also a small wooden hut nearby. The door appears unlocked." << endl;
     cout << endl;
     cout << "Will you:" << endl;
     cout << "[e] enter the hut; or," << endl;
     cout << "[f] follow the stream?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;

     if (answer == 'e') goto enter_hut;
     if (answer == 'f') goto follow_stream;
     goto unknown_forest;

enter_hut:
     cout << endl;
     cout << "You enter the small wooden hut." << endl;
     cout << endl;
     goto describe_hut;

follow_stream:
     cout << endl;
     cout << "You follow the course of the stream through the forest until you reach a point" << endl;
     cout << "where it suddenly ends." << endl;
     cout << endl;
     goto describe_streambed;

unknown_forest:
     cout << endl;
     cout << "I did not understand that answer." << endl;
     cout << endl;
     goto describe_forest;

describe_hut:
     cout << "You are inside a musty old wooden hut." << endl;
     cout << endl;

     if (have_key) goto describe_hut_with_key;

     cout << "There is a small metal key hanging from a hook on the wall. Will you:" << endl;
     cout << "[t] take the key; or," << endl;
     cout << "[g] go back outside?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;

     if (answer == 'g') goto leave_hut;
     if (answer == 't') goto take_key;
     goto unknown_hut;

describe_hut_with_key:
     cout << "There is a small metal key hook on the wall. Will you:" << endl;
     cout << "[r] return the key to the hook; or," << endl;
     cout << "[g] go back outside?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'g') goto leave_hut;
     if (answer == 'r') goto return_key;
     goto unknown_hut;

leave_hut:
     cout << endl;
     cout << "You leave the hut." << endl;
     cout << endl;
     goto describe_forest;

return_key:
     cout << endl;
     cout << "You return the small key to its hook." << endl;
     cout << endl;
     have_key = false;
     goto describe_hut;

unknown_hut:
     cout << endl;
     cout << "I did not understand that answer." << endl;
     cout << endl;
     goto describe_hut;

take_key:
     cout << endl;
     cout << "You take the small key and leave the hut." << endl;
     cout << endl;
     have_key = true;
     goto describe_forest;

describe_streambed:
     cout << "You are at the end of a small stream. It trickles down into a small hole in the" << endl;
     cout << "ground. Beyond the hole, the stream bed is dry. There is a large metal grate in" << endl;
     cout << "the dry earth." << endl;
     cout << endl;

     if (grate_locked && have_key) goto describe_grate_locked_and_have_key;
     if (grate_locked) goto return_for_key;
     if (have_key) goto describe_unlocked_grate_and_have_key;

     cout << "The grate is unlocked. Will you:" << endl;
     cout << "[e] enter through the grate; or," << endl;
     cout << "[g] go back upstream?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'g') goto return_to_forest;
     if (answer == 'e') goto enter_cave;
     goto unknown_streambed;

describe_grate_locked_and_have_key:
     cout << "The grate is locked. It looks like the key you have will fit the lock. Will you:" << endl;
     cout << "[u] use the key to open the grate; or," << endl;
     cout << "[g] go back upstream?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'g') goto return_to_forest;
     if (answer == 'u') goto unlock_grate;
     goto unknown_streambed;

describe_unlocked_grate_and_have_key:
     cout << "The grate is unlocked. Will you:" << endl;
     cout << "[l] lock the grate;" << endl;
     cout << "[e] enter through the grate; or," << endl;
     cout << "[g] go back upstream?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'g') goto return_to_forest;
     if (answer == 'e') goto enter_cave;
     if (answer == 'l') goto lock_grate;
     goto unknown_streambed;

return_to_forest:
     cout << endl;
     cout << "You follow the stream back into the forest." << endl;
     cout << endl;
     goto describe_forest;

unlock_grate:
     cout << endl;
     cout << "The key turns reluctantly in the rusty old lock." << endl;
     cout << endl;
     grate_locked = false;
     goto describe_streambed;

lock_grate:
     cout << endl;
     cout << "As you lock the grate you suddenly wake." << endl;
     cout << endl;
     grate_locked = true;
     goto failed_adventurer;

unknown_streambed:
     cout << endl;
     cout << "I did not understand that answer." << endl;
     cout << endl;
     goto describe_streambed;

return_for_key:
     cout << "The grate is locked. You'll need a key to open it. You go back upstream to look" << endl;
     cout << "for one." << endl;
     cout << endl;
     goto describe_forest;

enter_cave:
     cout << endl;
     cout << "You descend through the grate and into the darkness." << endl;
     cout << endl;
     goto describe_cave;

describe_cave:
     cout << "You are in a dank cavern. Before you, in the darkness, you can make out the" << endl;
     cout << "shape of an ancient dragon. The dragon bares its teeth and prepares to strike." << endl;
     cout << endl;
     cout << "Will you:" << endl;
     cout << "[f] fight the dragon; or," << endl;
     cout << "[r] run back through the grate?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'f') goto last_chance;
     if (answer == 'r') goto run;
     goto unknown_cave;

last_chance:
     cout << endl;
     cout << "Barehanded! Are you sure? Will you:" << endl;
     cout << "[f] fight the dragon barehanded; or," << endl;
     cout << "[r] think better of it and run back to the surface?" << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'f') goto kill_dragon;
     if (answer == 'r') goto run;
     goto unknown_cave;

run:
     cout << endl;
     cout << "Your heart races as you climb back out of the cave. But, as you slam the grate" << endl;
     cout << "shut behind you, you suddenly wake." << endl;
     cout << endl;
     goto survivor;

unknown_cave:
     cout << endl;
     cout << "I did not understand that answer." << endl;
     cout << endl;
     goto describe_cave;

kill_dragon:
     cout << endl;
     cout << "Incredibly, you fight and kill the dragon with your bare hands! You wake, with" << endl;
     cout << "newfound confidence. You are a true adventurer." << endl;
     cout << endl;
     goto the_end;

survivor:
     cout << "Your adventure is at an end. You have faced a dragon and yet live to tell the" << endl;
     cout << "tale. You are a true survivor." << endl;
     cout << endl;
     goto the_end;

failed_adventurer:
     cout << "Your adventure is at an end. You realize you do not have what it takes." << endl;
     cout << endl;

the_end:
     cout << "The end." << endl;

restart_or_quit:
     cout << endl;
     cout << "[r] Restart this game." << endl;
     cout << "[q] Quit." << endl;
     cout << endl;
     cout << ">";

     cin >> answer;
     if (answer == 'r') goto start_game;
     if (answer == 'q') goto quit;
     goto restart_or_quit;

quit:
     return 0;
}
